
param T;
set TIME ordered := 0..T;
set NODES;
param Parent{NODES} symbolic; # parent of nodes
param Probs{NODES}; # probability distribution of nodes

set ASSETS;
param Return{ASSETS, NODES}; # returns of assets at each node
#param TotalScenario := card(NODES) - 1;
param AveReturn{j in ASSETS} := sum{n in NODES}(Return[j,n]*Probs[n]);

set BENCHMARK;             #BENCHMARK = number of benchmark realization
param VBenchmk{BENCHMARK}; # values of benchmarks
param HBenchmk{BENCHMARK}; # 2nd order SD values of benchmarks - calculated


var slack2{BENCHMARK} >= 0;

block alm stochastic using (nd in NODES, Parent, Probs, st in TIME): {

  stages {0}: {
  	
  	var x_hold{ASSETS} >= 0;
    
    subject to StartBudget:
      sum{j in ASSETS} (x_hold[j]) = 1;
      
    maximize objFunc: sum{j in ASSETS} (x_hold[j]*AveReturn[j]);
  }

  stages {T}: {

    var slack1{BENCHMARK} >= 0;
	var risk{BENCHMARK} >= 0;
	
    subject to StochasticDominance1{l in BENCHMARK}:
      sum{j in ASSETS}(ancestor(1).x_hold[j]*Return[j,nd]) + risk[l] - slack1[l] = VBenchmk[l];

    subject to StochasticDominance2{l in BENCHMARK}:
      Exp(risk[l]) + slack2[l] = HBenchmk[l];
    
  }
}
